package com.qiulingcloud.commonsserver.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;


/**
 * @Author：zhangqiang
 * @Description：
 * @Date：Created in 12:14 2020/4/25
 * @Modified By：
 */
@Slf4j
public class CodeGenerator {

    //代码生成根目录
    private static String outPutDir = "D:/qiuling-parent/qiuling-commons/commons-server/src/main/java";
    //生成代码所在的包名
    private static String codePackage = "com.qiulingcloud.commonsserver";
    //生成文件的包名（Controller层RequestMapping的路径名+实体类名）
    private static String moduleName = "";
    //数据库用户名
    private static String dbUserName = "root";
    //数据库用户密码
    private static String dbPassword = "root";
    //数据库url
    private static String dbUrl = "jdbc:mysql://localhost:3308/qiuling_iot?useSSL=false&useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT&allowPublicKeyRetrieval=true";
    //数据库驱动
    private static String dbDriver5 = "com.mysql.jdbc.Driver";
    private static String dbDriver8 = "com.mysql.cj.jdbc.Driver";
    //是否覆盖原文件
    private static boolean fileOverride = true;
    //数据库要生成的表名
    private static String[] includeTable;
    //排除的表名
    private static String[] excludeTable;

    public CodeGenerator(String outPutDir, String dbUserName, String dbPassword, String dbUrl, String moduleName) {
        this.outPutDir = outPutDir;
        this.dbUserName = dbUserName;
        this.dbPassword = dbPassword;
        this.dbUrl = dbUrl;
        this.moduleName = moduleName;
    }

    private void setIncludeTable(String[] includeTable) {
        this.includeTable = includeTable;
    }

    /**
     * @description 初始化配置器
     * <br/>
     * @param
     * @return void
     * @author zhangqiang
     * @date 20:49 2019/12/8
     */
    public void execute() {
        if (StringUtils.isEmpty(CodeGenerator.dbUserName)) {
            log.error("数据库连接信息不能为空");
        } else {
            AutoGenerator mpg = new AutoGenerator();
            mpg.setGlobalConfig(getGlobalConfig());
            mpg.setDataSource(getDataSourceConfig());
            mpg.setPackageInfo(getPackageConfig());
            setStrategyConfig(mpg);
            log.info("全局配置初始化成功");
            mpg.execute();
        }
    }

    /**
     * @description 全局配置
     * <br/>
     * @param
     * @return com.baomidou.mybatisplus.generator.config.GlobalConfig
     * @author zhangqiang
     * @date 22:00 2019/12/8
     */
    private GlobalConfig getGlobalConfig() {
        GlobalConfig gc = new GlobalConfig();
        gc.setOutputDir(CodeGenerator.outPutDir);
        gc.setFileOverride(CodeGenerator.fileOverride);
        //默认true ,是否打开输出目录
        gc.setOpen(false);
        // 默认false,是否开启二级缓存
        gc.setEnableCache(false);
        // 作者
        gc.setAuthor("zhangqiang");
        // 默认false
        gc.setSwagger2(true);
        // 默认false
        gc.setBaseResultMap(true);
        // 时间策略 默认TIME_PACK
        gc.setDateType(DateType.TIME_PACK);
        // 默认false  和baseModel相似
        gc.setBaseColumnList(true);
        // 自定义文件命名，注意 %s 会自动填充表实体属性！
        gc.setEntityName("%s");
        gc.setControllerName("%sController");
        gc.setServiceName("%sService");
        gc.setServiceImplName("%sServiceImpl");
        gc.setMapperName("%sMapper");
        gc.setXmlName("%sMapper");
        // 指定生成的主键类型
        gc.setIdType(IdType.UUID);
        return gc;
    }

    /**
     * @description 数据库配置
     * <br/>
     * @param
     * @return com.baomidou.mybatisplus.generator.config.DataSourceConfig
     * @author zhangqiang
     * @date 21:58 2019/12/8
     */
    private DataSourceConfig getDataSourceConfig() {
        DataSourceConfig dc = new DataSourceConfig();
        // 数据库信息查询 //默认mysql
        dc.setDbQuery(new MySqlQuery());
        // 数据库类型
        dc.setDbType(DbType.MYSQL);
        //类型转换 默认mysql
        dc.setTypeConvert(new MySqlTypeConvert());
        dc.setUrl(CodeGenerator.dbUrl);
        dc.setDriverName(CodeGenerator.dbDriver8);
        dc.setUsername("root");
        dc.setPassword("root");
        return dc;
    }

    /**
     * @description 生成包配置
     * <br/>
     * @param
     * @return com.baomidou.mybatisplus.generator.config.PackageConfig
     * @author zhangqiang
     * @date 21:56 2019/12/8
     */
    private PackageConfig getPackageConfig() {
        PackageConfig pc = new PackageConfig();
        pc.setParent(CodeGenerator.codePackage);
        pc.setModuleName(CodeGenerator.moduleName);
        return pc;
    }

    /**
     * @description 生成策略配置
     * <br/>
     * @param mpg
     * @return void
     * @author zhangqiang
     * @date 21:48 2019/12/8
     */
    private void setStrategyConfig(AutoGenerator mpg) {
        StrategyConfig strategy = new StrategyConfig();
        //开启下划线自动转驼峰
        strategy.setNaming(NamingStrategy.underline_to_camel);
        //需要生成的表
        strategy.setInclude(CodeGenerator.includeTable);
        //排除生成的表
        strategy.setExclude(CodeGenerator.excludeTable);
        //生成Rest风格的controller
        strategy.setRestControllerStyle(true);
        //生成实体类时lombok模型（默认false）
        strategy.setEntityLombokModel(true);
        // 生成字段带注释
        strategy.setEntityTableFieldAnnotationEnable(true);
        mpg.setStrategy(strategy);
    }

    /**
     * 代码生成
     * @param args
     */
    public static void main(String[] args) {
        CodeGenerator mh = new CodeGenerator(CodeGenerator.outPutDir,
                CodeGenerator.dbUserName,
                CodeGenerator.dbPassword,
                CodeGenerator.dbUrl,
                CodeGenerator.moduleName);
        // 需要自动生成的table，传数组
        mh.setIncludeTable(new String []{"sys_user","test_order"});
        mh.execute();
    }

}